package com.hyfrogx.modules.manage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyfrogx.common.exception.MyException;
import com.hyfrogx.common.utils.QueryExt;
import com.hyfrogx.common.utils.ShiroUtils;
import com.hyfrogx.modules.app.form.AdApkFrom;
import com.hyfrogx.modules.app.utils.FrogConstant;
import com.hyfrogx.modules.job.entity.HyAdJobEntity;
import com.hyfrogx.modules.job.service.HyAdJobService;
import com.hyfrogx.modules.job.task.AdTask;
import com.hyfrogx.modules.manage.dao.HyAdDao;
import com.hyfrogx.modules.manage.entity.HyAdEntity;
import com.hyfrogx.modules.manage.form.ad.AdForm;
import com.hyfrogx.modules.manage.form.ad.AdPutawayForm;
import com.hyfrogx.modules.manage.form.ad.AdVo;
import com.hyfrogx.modules.manage.service.HyAdService;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @version 1.0.0
 * @Author: lfh
 * @Date: 2019/10/16 14:05
 * @Company 汉咏科技
 */
@Service
public class HyAdServiceImpl extends ServiceImpl<HyAdDao, HyAdEntity> implements HyAdService {

    @Autowired
    private HyAdJobService hyAdJobService;

    /**
     * @param TaskTime
     * @return
     * 任务时间转换成Cron定时器格式
     */
    public static String getCron(Date  TaskTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
        String formatTimeStr = "";
        if (TaskTime != null) {
            formatTimeStr = sdf.format(TaskTime);
        }
        return formatTimeStr;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveAd(AdForm adForm) {
        HyAdEntity hyAdEntity = BeanUtil.toBean(adForm,HyAdEntity.class);
        //广告基本参数设置
        Long id = ShiroUtils.getUserId();
        hyAdEntity.setUid(id);
        hyAdEntity.setCreateDate(new Date());
        //如果上架方式为空。设置广告状态为待上架
        if (ObjectUtil.isNull(hyAdEntity.getReleaseType()))
        {
            //状态设置为0
            hyAdEntity.setStatus(FrogConstant.AdStatus.WAIT.getValue());
        }
        //如果上架方式不为空，判断上架类型
        else
        {
            //如果是立即上架
            if (hyAdEntity.getReleaseType().equals(FrogConstant.AdReleaseType.IMMEDIATE.getValue()))
            {
                //设置状态为已上架,设置当前时间为上架时间
                hyAdEntity.setStatus(FrogConstant.AdStatus.HAVING.getValue());
                hyAdEntity.setReleaseDate(new Date());
            }
            //如果是定时上架
            else if (hyAdEntity.getReleaseType().equals(FrogConstant.AdReleaseType.TIMING.getValue()))
            {
                Assert.notNull(hyAdEntity.getTaskTime(),"定时上架时间为空");
                //设置状态为待上架
                hyAdEntity.setStatus(FrogConstant.AdStatus.WAIT.getValue());
                //提前保存，获取定时广告主键id
                Boolean b = this.save(hyAdEntity);
                //创建定时任务实体
                createAdJob(adForm,hyAdEntity.getId());
                return b;
            }
        }
        return this.save(hyAdEntity);
    }

    @Override
    public IPage<AdVo> getAdsByMap(QueryExt queryExt, Map pmap) {
        List<AdVo> list = this.baseMapper.getAdsByMap(queryExt,pmap);
        queryExt.setRecords(list);
        return queryExt;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateAd(AdForm adForm) {
        Assert.notNull(adForm.getId(),"广告id为空");
        HyAdEntity hyAdEntity = BeanUtil.toBean(adForm,HyAdEntity.class);
        //广告基本参数设置
        Long id = ShiroUtils.getUserId();
        hyAdEntity.setUid(id);
        hyAdEntity.setUpdateDate(new Date());
        //如果上架方式不为空。进行上架操作
        if (ObjectUtil.isNotNull(adForm.getReleaseType()))
        {
            //如果是立即上架
            if (hyAdEntity.getReleaseType().equals(FrogConstant.AdReleaseType.IMMEDIATE.getValue()))
            {
                //设置状态为已上架,设置当前时间为上架时间
                hyAdEntity.setStatus(FrogConstant.AdStatus.HAVING.getValue());
                hyAdEntity.setReleaseDate(new Date());
            }
            //如果是定时上架
            else if (hyAdEntity.getReleaseType().equals(FrogConstant.AdReleaseType.TIMING.getValue()))
            {
                Assert.notNull(hyAdEntity.getTaskTime(),"定时上架时间为空");
                //设置状态为待上架
                hyAdEntity.setStatus(FrogConstant.AdStatus.WAIT.getValue());

                //创建定时任务实体
                createAdJob(adForm,hyAdEntity.getId());
            }
        }
        return this.updateById(hyAdEntity);
    }

    /**
     * 插入或者更新时创建定时任务代码汇总
     * @return
     */
    public void createAdJob(AdForm adForm,Integer id)
    {
        HyAdJobEntity hyAdJobEntity = new HyAdJobEntity();
        setAdJob(hyAdJobEntity);
        //参数设置为广告id
        hyAdJobEntity.setParams(String.valueOf(id));
        //设置定时时间,从表单获取时间转换成Cron格式
        hyAdJobEntity.setCronExpression(getCron(adForm.getTaskTime()));
        System.out.println("Cron定时时间："+hyAdJobEntity.getCronExpression());
        //创建定时任务
        hyAdJobService.saveAdJob(hyAdJobEntity);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean putaway(AdPutawayForm adPutawayForm) {
        HyAdEntity hyAdEntity = this.getById(adPutawayForm.getId());
        //基础参数设置
        Long userId = ShiroUtils.getUserId();
        hyAdEntity.setUpdateDate(new Date());
        hyAdEntity.setUid(userId);
        //如果是立即上架
        if (adPutawayForm.getReleaseType().equals(FrogConstant.AdReleaseType.IMMEDIATE.getValue()))
        {
            //设置状态，上架时间，上架类型
            hyAdEntity.setStatus(FrogConstant.AdStatus.HAVING.getValue());
            hyAdEntity.setReleaseDate(new Date());
            hyAdEntity.setReleaseType(FrogConstant.AdReleaseType.IMMEDIATE.getValue());
        }
        //如果是定时上架
        else {
            //设置状态，定时任务时间，上架类型
            hyAdEntity.setStatus(FrogConstant.AdStatus.WAIT.getValue());
            hyAdEntity.setReleaseType(FrogConstant.AdReleaseType.TIMING.getValue());
            hyAdEntity.setTaskTime(adPutawayForm.getTaskTime());
            //创建定时任务，设置Cron，params，bean名称，方法名称
            HyAdJobEntity hyAdJobEntity = new HyAdJobEntity();
            setAdJob(hyAdJobEntity);
            hyAdJobEntity.setCronExpression(getCron(adPutawayForm.getTaskTime()));
            hyAdJobEntity.setParams(String.valueOf(adPutawayForm.getId()));
            hyAdJobService.saveAdJob(hyAdJobEntity);
        }
        return this.updateById(hyAdEntity);
    }

    /**
     * 设置广告定时任务
     * @param hyAdJobEntity
     */
    public void setAdJob(HyAdJobEntity hyAdJobEntity)
    {
        hyAdJobEntity.setBeanName(AdTask.BEANNAME);
        hyAdJobEntity.setMethodName(AdTask.METHODNAME);
    }

    @Override
    public Boolean AdsoldOutById(Integer id) {
        return soldOutAndRepeal(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean AdRepealById(Integer id) {
        //删除定时任务（逻辑删除）
        hyAdJobService.deleteAdJob(id);
        //判断当前时间距离上架时间是否大于半个小时
        HyAdEntity hyAdEntity = this.getById(id);
        Long taskTime = hyAdEntity.getTaskTime().getTime();
        Long nowTime = System.currentTimeMillis();
        if (nowTime+1800000>taskTime)
        {
            throw new MyException("距离发布时间不到半小时，无法撤销");
        }

        return soldOutAndRepeal(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Integer id) {
        //如果有定时任务。删除定时任务（逻辑删除）
        if (hyAdJobService.queryAdJob(id))
        {
            hyAdJobService.deleteAdJob(id);
        }
        return this.removeById(id);
    }

    /**
     * app端获取广告列表
     * @param adApkFrom
     * @return
     */
    @Override
    public List<AdVo> getAdList(AdApkFrom adApkFrom) {
        List<AdVo> list = this.baseMapper.getAdList(adApkFrom);
        return list;
    }

    @Override
    public HyAdEntity getAdById(Integer id) {
        HyAdEntity adEntity = this.getOne(new QueryWrapper<HyAdEntity>().eq("id",id).eq("status",FrogConstant.AdStatus.HAVING.getValue()));
        return adEntity;
    }

    @Override
    public List<String> selectByParam(String str) {
        return this.baseMapper.selectByParam(str);
    }

    /**
     * 下架和撤销共同参数设置
     * @return
     */
    public Boolean soldOutAndRepeal(Integer id)
    {
        HyAdEntity hyAdEntity = new HyAdEntity();
        hyAdEntity.setId(id);
        hyAdEntity.setStatus(FrogConstant.AdStatus.OUT.getValue());
        //设置操作人和更新时间
        Long userId = ShiroUtils.getUserId();
        hyAdEntity.setUid(userId);
        hyAdEntity.setUpdateDate(new Date());
        return this.updateById(hyAdEntity);
    }



}
